﻿using Ding.HttpHelper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using SelfService.Model.Models;
using SelfService.XinXing.Models;
using TT;
using WalkingTec.Mvvm.Core;

namespace SelfService.XinXing
{
    /// <summary>
    /// 医生排班信息同步服务
    /// </summary>
    public class DoctorScheduleDataSyncService : BackgroundService
    {
        private readonly IServiceProvider _service;
        private readonly ReservationConfig _config;

        public DoctorScheduleDataSyncService(IServiceProvider service, IOptions<ReservationConfig> options)
        {
            _service = service;
            _config = options.Value;
        }

        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return Task.Factory.StartNew(async () =>
            {
                var setting = new JsonSerializerSettings()
                {
                    ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
                };
                do
                {
                    var scope = _service.CreateScope();
                    var wtm = scope.ServiceProvider.GetRequiredService<WTMContext>();
                    try
                    {
                        string postData = JsonConvert.SerializeObject(new
                        {
                            Channel = _config.ReservationChannel,
                            ScheduDate = DateTime.Now.ToString("yyyy-MM-dd"),
                        }, setting);
                        var httpItem = new HttpItem
                        {
                            URL = $"{_config.ReservationHost}/shm/registration/scheduEmps",
                            Method = "POST",
                            ContentType = "application/json",
                            Postdata = postData
                        };
                        HttpResult result = null;
                        await Task.Run(() => { result = new HttpHelper().GetHtml(httpItem); }, stoppingToken);
                        if (result.Html.TryJsonParse(out ReservationResult<ReservationResultListInfo<ReservationDoctorRoomInfo>> response, out var error))
                        {
                            if (response.Code == "1000")
                            {
                                foreach (var element in response.Message.List)
                                {
                                    //查找诊室, 如果不存在则创建, 如果存在则更新
                                    var room = await wtm.DC.Set<SysRoom>()
                                        .FirstOrDefaultAsync(e => e.HisId == element.RoomId, cancellationToken: stoppingToken);
                                    if (room == null)
                                    {
                                        //新建诊室
                                        room = new SysRoom();
                                        room.HisId = element.RoomId;
                                        room.Name = element.RoomName;
                                        room.Code = element.RoomCode;
                                        room.DepartmentId = element.DepartmentId;
                                        room.DepartmentCode = element.DepartmentCode;
                                        room.DepartmentName = element.DepartmentName;
                                        room.ID = Guid.NewGuid();
                                        room.CreateTime = DateTime.Now;
                                        room.CreateBy = "排班更新服务";
                                        room.UpdateTime = DateTime.Now;
                                        room.UpdateBy = "排班更新服务";
                                        await wtm.DC.Set<SysRoom>().AddAsync(room, stoppingToken);
                                        await wtm.DC.SaveChangesAsync(stoppingToken);
                                    }
                                    else
                                    {
                                        //更新诊室
                                        var isModify = false;
                                        if (room.Name != element.RoomName)
                                        {
                                            isModify = true;
                                            room.Name = element.RoomName;
                                        }
                                        if (room.Code != element.RoomCode)
                                        {
                                            isModify = true;
                                            room.Code = element.RoomCode;
                                        }
                                        if (room.DepartmentId != element.DepartmentId)
                                        {
                                            isModify = true;
                                            room.DepartmentId = element.DepartmentId;
                                        }
                                        if (room.DepartmentCode != element.DepartmentCode)
                                        {
                                            isModify = true;
                                            room.DepartmentCode = element.DepartmentCode;
                                        }
                                        if (room.DepartmentName != element.DepartmentName)
                                        {
                                            isModify = true;
                                            room.DepartmentName = element.DepartmentName;
                                        }
                                        if (isModify)
                                        {
                                            room.UpdateTime = DateTime.Now;
                                            room.UpdateBy = "排班更新服务";
                                            await wtm.DC.SaveChangesAsync(stoppingToken);
                                        }
                                    }

                                    if (element.DoctorName == "吕志刚")
                                    {
                                        var a = 1;
                                    }
                                    //查找医生, 如果不存在则创建, 如果存在则更新
                                    var doctor = wtm.DC.Set<SysDoctor>().FirstOrDefault(e => e.Code == element.DoctorCode);
                                    if (doctor == null)
                                    {
                                        //新增医生
                                        doctor = new SysDoctor();
                                        doctor.Code = element.DoctorCode;
                                        doctor.RoomId = room.ID;
                                        doctor.Name = element.DoctorName;
                                        doctor.DoctorLevel = element.LevelName;
                                        doctor.Info = element.Summary;
                                        doctor.ID = Guid.NewGuid();
                                        doctor.ClinicFee = element.Clinicfee;
                                        doctor.Photo = element.HeadImage.IsNullOrWhiteSpace() ? "http://192.168.0.134:8001/images/doctor.jpg" : $"{_config.ReservationHost}:9000/xxkj/{element.HeadImage}";
                                        doctor.ExamFee = element.Examfee;
                                        doctor.TotalFee = element.Totalfee;
                                        doctor.CreateTime = DateTime.Now;
                                        doctor.Workday = element.ScheduDate;
                                        doctor.CreateBy = "查询排班服务";
                                        doctor.UpdateTime = DateTime.Now;
                                        doctor.UpdateBy = "查询排班服务";
                                        await wtm.DC.Set<SysDoctor>().AddAsync(doctor, stoppingToken);
                                        await wtm.DC.SaveChangesAsync(stoppingToken);
                                    }
                                    else
                                    {
                                        //更新医生
                                        var isModify = false;
                                        var photo = element.HeadImage.IsNullOrWhiteSpace() ? "http://192.168.0.134:8001/images/doctor.jpg" : $"{_config.ReservationHost}:9000/xxkj/{element.HeadImage}";
                                        if (doctor.Photo != photo)
                                        {
                                            isModify = true;
                                            doctor.Photo = photo;
                                        }
                                        if (doctor.RoomId != room.ID)
                                        {
                                            isModify = true;
                                            doctor.RoomId = room.ID;
                                        }
                                        if (doctor.Code != element.DoctorCode)
                                        {
                                            isModify = true;
                                            doctor.Code = element.DoctorCode;
                                        }
                                        if (doctor.Name != element.DoctorName)
                                        {
                                            isModify = true;
                                            doctor.Name = element.DoctorName;
                                        }
                                        if (doctor.DoctorLevel != element.LevelName)
                                        {
                                            isModify = true;
                                            doctor.DoctorLevel = element.LevelName;
                                        }
                                        if (doctor.Info != element.Summary)
                                        {
                                            isModify = true;
                                            doctor.Info = element.Summary;
                                        }
                                        if (doctor.ClinicFee != element.Clinicfee)
                                        {
                                            isModify = true;
                                            doctor.ClinicFee = element.Clinicfee;
                                        }
                                        if (doctor.ExamFee != element.Examfee)
                                        {
                                            isModify = true;
                                            doctor.ExamFee = element.Examfee;
                                        }
                                        if (doctor.TotalFee != element.Totalfee)
                                        {
                                            isModify = true;
                                            doctor.TotalFee = element.Totalfee;
                                        }
                                        if (doctor.Workday != element.ScheduDate)
                                        {
                                            isModify = true;
                                            doctor.Workday = element.ScheduDate;
                                        }
                                        if (isModify)
                                        {
                                            doctor.UpdateTime = DateTime.Now;
                                            doctor.UpdateBy = "查询排班服务";
                                            await wtm.DC.SaveChangesAsync(stoppingToken);
                                        }
                                    }

                                    //查找出排班列表中该医生所有的排班信息, 新增到排班信息, 然后移除旧的不存在的排班信息
                                    var doctors = response.Message.List.Where(e => e.DoctorCode == doctor.Code);
                                    var list = new List<Guid>();
                                    foreach (var item in doctors)
                                    {
                                        var timeInterval = await wtm.DC.Set<SysTimeInterval>()
                                            .FirstOrDefaultAsync(e => e.Name == item.AttendanceName,
                                                cancellationToken: stoppingToken);
                                        if (timeInterval == null)
                                        {
                                            timeInterval = new SysTimeInterval()
                                            {
                                                Name = item.AttendanceName,
                                                ID = Guid.NewGuid()
                                            };
                                            await wtm.DC.Set<SysTimeInterval>().AddAsync(timeInterval, stoppingToken);
                                            await wtm.DC.SaveChangesAsync(stoppingToken);
                                        }

                                        var doctorWorkTimeInterval = await wtm.DC.Set<DoctorWorkTimeInterval>()
                                            .FirstOrDefaultAsync(e =>
                                                e.DoctorId == doctor.ID && e.TimeIntervalId == timeInterval.ID, cancellationToken: stoppingToken);
                                        if (doctorWorkTimeInterval == null)
                                        {
                                            doctorWorkTimeInterval = new DoctorWorkTimeInterval
                                            {
                                                DoctorId = doctor.ID,
                                                TimeIntervalId = timeInterval.ID,
                                                ID = Guid.NewGuid(),
                                                CreateBy = "查询排班服务",
                                                CreateTime = DateTime.Now,
                                                UpdateBy = "查询排班服务",
                                                UpdateTime = DateTime.Now
                                            };
                                            await wtm.DC.Set<DoctorWorkTimeInterval>().AddAsync(doctorWorkTimeInterval, stoppingToken);
                                            await wtm.DC.SaveChangesAsync(stoppingToken);
                                        }
                                        list.Add(doctorWorkTimeInterval.ID);
                                        await wtm.DC.SaveChangesAsync(stoppingToken);
                                    }
                                    //移除旧的不存在的排班信息
                                    var removes = await wtm.DC.Set<DoctorWorkTimeInterval>()
                                        .Where(e => e.DoctorId == doctor.ID && !list.Contains(e.ID))
                                        .ToListAsync(cancellationToken: stoppingToken);
                                    if (removes.Count > 0) wtm.DC.Set<DoctorWorkTimeInterval>().RemoveRange(removes);
                                    await wtm.DC.SaveChangesAsync(stoppingToken);
                                }

                                var codes = response.Message.List.Select(e => e.DoctorCode);
                                var notWorkDoctors = await wtm.DC.Set<SysDoctor>()
                                    .Where(e => e.Workday >= DateTime.Today && !codes.Contains(e.Code)).ToListAsync(cancellationToken: stoppingToken);
                                if (notWorkDoctors.Count > 0)
                                {
                                    notWorkDoctors.ForEach(element =>
                                    {
                                        element.Workday = new DateTime();
                                    });
                                    await wtm.DC.SaveChangesAsync(stoppingToken);
                                }
                                await Task.Delay(5000, stoppingToken);
                                continue;
                            }
                        }
                        wtm.DoLog($"查询医生排班信息发生错误:{error}, 返回信息:{result.Html}", ActionLogTypesEnum.Exception, "新星综合预约", "DoctorScheduleDataSyncService");
                    }
                    catch (Exception e)
                    {
                        wtm.DoLog($"查询医生排班信息异常:{JsonConvert.SerializeObject(e)}", ActionLogTypesEnum.Exception, "新星综合预约", "DoctorScheduleDataSyncService");
                    }
                    await Task.Delay(5000, stoppingToken);
                } while (!stoppingToken.IsCancellationRequested);
            }, stoppingToken);
        }
    }
}
